/**
 * 
 */
package ar.edu.utn.frsf.cidisi.ginet.generation.upcolbpip2cginet.elementstemplate;

import org.eclipse.emf.common.util.EList;
import org.pnml.tools.epnk.pnmlcoremodel.AnnotationGraphics;
import org.pnml.tools.epnk.pnmlcoremodel.Coordinate;
import org.pnml.tools.epnk.pnmlcoremodel.Name;
import org.pnml.tools.epnk.pnmlcoremodel.PnmlcoremodelFactory;
import org.pnml.tools.epnk.pntypes.hlpng.pntd.hlpngdefinition.Declaration;

import ar.edu.utn.frsf.cidisi.ginet.abstractginet.Arc;
import ar.edu.utn.frsf.cidisi.ginet.abstractginet.Page;
import ar.edu.utn.frsf.cidisi.ginet.abstractginet.Place;
import ar.edu.utn.frsf.cidisi.ginet.abstractginet.RefPlace;
import ar.edu.utn.frsf.cidisi.ginet.abstractginet.Transition;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.BusinessMessage;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.ControlFlowSegment;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.InteractionPath;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.InteractionProtocolElement;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.Loop;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.LoopType;

/**
 * @author Neri
 *
 */
public class LoopUpcolbpipStructure extends ChoreographyStructure {
	
	public LoopUpcolbpipStructure(Integer i){		
		super();
		this.pos = i;
		//Name		
		AnnotationGraphics graphicsName = PnmlcoremodelFactory.eINSTANCE
				.createAnnotationGraphics();
		
		Name nameLabel = PnmlcoremodelFactory.eINSTANCE.createName();
		
		Coordinate coordinate2 = PnmlcoremodelFactory.eINSTANCE.createCoordinate();
		
		coordinate2.setX(-9);
		coordinate2.setY( -39);
		
		graphicsName.setOffset(coordinate2);
		
		nameLabel.setText("LOOP");
		nameLabel.setGraphics(graphicsName);
		
		this.abstractPage.setName(nameLabel);
	}
	
	@Override
	public void createPageStructure(InteractionProtocolElement element, Place placeIn, Place placeOut, EList<Declaration> ginetDeclarations, Place termination, EList<BusinessMessage> messages){		
		this.fillVarDeclAndNameSort(ginetDeclarations);
		
		this.setTypeNameLoop(((Loop)element).getLoopType());
		
		EList<InteractionPath> interP = ((ControlFlowSegment)element).getInteractionPath(); 
		
		if(((Loop)element).getLoopType().equals(LoopType.WHILE)){
			this.setPageName(element);
			
			RefPlace refPlaceIn = this.createRefPlace("InPlace",  1, 2, "InPlace", -4, -4, "1", placeIn);
			
			Transition transitionIn = this.createTransition("transitionIn", 2, 2, "transitionIn", -4, -9, "1", "1", null);
			
			Place placeInWhile = createPlace("placeInWhile", 3, 2, "placeInWhile", -4, -4, this.getVarDec("gi"), 6, 21, true, "1");
			
			Arc arcIn = this.createArc("", this.getVarDec("gi"), -37, -3, refPlaceIn, transitionIn);
			this.abstractPage.getObject().add(arcIn);
			
			Arc arcIn2 = this.createArc("", this.getVarDec("gi"), -37, -3, transitionIn, placeInWhile);
			this.abstractPage.getObject().add(arcIn2);
			this.abstractPage.getObject().add(transitionIn);
			this.abstractPage.getObject().add(placeInWhile);
			
			Transition transitionContinue = this.createTransition("continue", 5, 1, "continue", -4, -9, "1", "1", null);

			Transition transitionFinalize = this.createTransition("finalize_loop", 4, 3, "finalize_loop", -4, -9, "1", "1", null);
			
			Place placeIterate = createPlace("iterate", 5, 2, "iterate", -4, -4, this.getVarDec("gi"), 6, 21, true, "1");
			
			RefPlace refPlaceOut = this.createRefPlace("OutPlace", 5, 3, "OutPlace", -4, -4, "1", placeOut);
			
			for(int i = 0; i< interP.size(); i++){
				
				Page page = createPage("content", 4, 2, "content", -9, -39);
					
				this.createInteractionProtocol(interP.get(i), 0, page, placeInWhile, placeIterate, ginetDeclarations, termination, messages);
			
				this.abstractPage.getObject().add(page);				
				
				i = interP.size();
			}
			Arc arcPItTCon = this.createArc("", this.getVarDec("gi"), -37, -3, placeIterate, transitionContinue);
			Arc arcPInTFin = this.createArc("", this.getVarDec("gi"), -37, -3, placeInWhile, transitionFinalize);
			
			Arc arcTFinPOut = this.createArc("", this.getVarDec("gi"), -37, -3, transitionFinalize, refPlaceOut);
			
			Arc arcTConPIn = this.createArc("", this.getVarDec("gi"), -37, -3, transitionContinue, placeInWhile);

			
			this.abstractPage.getObject().add(arcPItTCon);
			this.abstractPage.getObject().add(arcPInTFin);
			this.abstractPage.getObject().add(arcTFinPOut);
			this.abstractPage.getObject().add(arcTConPIn);
			
			this.abstractPage.getObject().add(refPlaceIn);
			this.abstractPage.getObject().add(refPlaceOut);

			this.abstractPage.getObject().add(placeIterate);
			
			this.abstractPage.getObject().add(transitionContinue);
			this.abstractPage.getObject().add(transitionFinalize);
		}else{
			
			if(element.getName() != null && element.getName().toUpperCase().startsWith(this.abstractPage.getName().getText())){
				this.abstractPage.getName().setText(element.getName()+LoopType.UNTIL.toString() + this.pos);
			}else if(element.getName() == null){
				this.abstractPage.getName().setText(this.abstractPage.getName().getText()+ LoopType.UNTIL.toString()+ this.pos);
			}else{
				this.abstractPage.getName().setText(this.abstractPage.getName().getText()+ LoopType.UNTIL.toString() +element.getName()+ this.pos);
			}
			
			RefPlace refPlaceIn = this.createRefPlace("InPlace",  1, 2, "InPlace", -4, -4, "1", placeIn);
			
			Transition transitionIn = this.createTransition("transitionIn", 2, 2, "transitionIn", -4, -9, "1", "1", null);
			
			Place placeInUntil = createPlace("placeInUntil", 3, 2, "placeInUntil", -4, -4, this.getVarDec("gi"), 6, 21, true, "1");
			
			Arc arcIn = this.createArc("", this.getVarDec("gi"), -37, -3, refPlaceIn, transitionIn);
			this.abstractPage.getObject().add(arcIn);
			
			Arc arcIn2 = this.createArc("", this.getVarDec("gi"), -37, -3, transitionIn, placeInUntil);
			this.abstractPage.getObject().add(arcIn2);
			this.abstractPage.getObject().add(transitionIn);
			this.abstractPage.getObject().add(placeInUntil);
			
			Transition transitionContinue = this.createTransition("continue", 5, 1, "continue", -4, -9, "1", "1", null);

			Transition transitionFinalize = this.createTransition("finalize_loop", 5, 3, "finalize_loop", -4, -9, "1", "1", null);
			
			Place placeIterate = createPlace("iterate", 5, 2, "iterate", -4, -4, this.getVarDec("gi"), 6, 21, true, "1");
			
			RefPlace refPlaceOut = this.createRefPlace("OutPlace", 5, 4, "OutPlace", -4, -4, "1", placeOut);
			
			for(int i = 0; i<interP.size(); i++){
									
				Page page = createPage("content", 4, 2, "content", -9, -39);
				
				this.createInteractionProtocol(interP.get(i), 0, page, placeInUntil, placeIterate, ginetDeclarations, termination, messages);

				this.abstractPage.getObject().add(page);
				
				i = interP.size();
			}
			Arc arcPItTCon = this.createArc("", this.getVarDec("gi"), -37, -3, placeIterate, transitionContinue);
			Arc arcPItTFin = this.createArc("", this.getVarDec("gi"), -37, -3, placeIterate, transitionFinalize);
			
			Arc arcTFinPOut = this.createArc("", this.getVarDec("gi"), -37, -3, transitionFinalize, refPlaceOut);
			
			Arc arcTConPIn = this.createArc("", this.getVarDec("gi"), -37, -3, transitionContinue, placeInUntil);
			
			this.abstractPage.getObject().add(arcPItTCon);
			this.abstractPage.getObject().add(arcPItTFin);
			this.abstractPage.getObject().add(arcTFinPOut);
			this.abstractPage.getObject().add(arcTConPIn);
			
			this.abstractPage.getObject().add(refPlaceIn);
			this.abstractPage.getObject().add(refPlaceOut);
			
			this.abstractPage.getObject().add(placeIterate);
			
			this.abstractPage.getObject().add(transitionContinue);
			this.abstractPage.getObject().add(transitionFinalize);
		}
	}

	private void setTypeNameLoop(LoopType loopType) {

		String type = loopType.getName();
		
		String name = this.abstractPage.getName().getText();
		
		String nametype = name.substring(0, "Loop".length()) + type + name.substring("Loop".length());
		
		this.setName(this.abstractPage, nametype);		
	}
}